package com.quectel.cms.controller.device;


import com.quectel.cms.controller.BaseController;
import com.quectel.util.aspect.log.annotation.Log;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.constant.global.annotation.RequireTenants;
import com.quectel.constant.sys.SysConstants;
import com.quectel.core.module.device.dto.DeviceColumnDto;
import com.quectel.core.module.device.dto.DeviceTypeDto;
import com.quectel.core.module.device.service.DeviceColumnService;
import com.quectel.core.module.device.service.DeviceTypeService;
import com.quectel.util.common.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 * @date 2019-05-31 12:10:45
 */
@RestController
@RequestMapping("deviceColumn")
@Tag(name = "DeviceColumnController", description = "设备物模型相关api")
public class DeviceColumnController extends BaseController {

    @DubboReference
    private DeviceColumnService deviceColumnService;

    @DubboReference
    private DeviceTypeService deviceTypeService;

    /**
     * 上传字段
     */
    @RequestMapping(value = "uploadColumns", method = RequestMethod.POST)
    @RequireTenants(values = SysConstants.SYS_TOP_TENANT_CODE)
    @Operation(summary = "上传设备物模型字段")
    public Response<Map> uploadColumns(@RequestParam(value = "file") MultipartFile multiFile,
                                       @RequestParam(value = "deviceTypeId") Object deviceTypeId) throws Exception {

        List<Object> responseDataList = new ArrayList<Object>();
        if ("undefined".equals(deviceTypeId)) {
            return Response.error("未选中设备类型！");
        }
        //判断文件是否为空
        if (multiFile == null) {
            return Response.error("文件为空！");
        }
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        if (!".xls".contains(prefix) && !".XLS".contains(prefix)) {
            return Response.error("文件必须是.xls格式！");
        }
        List<Map<Integer, String>> analysisList = new ArrayList<>();
        try {
            // 用当前时间作为文件名，防止生成的临时文件重复
            File file = File.createTempFile(System.currentTimeMillis() + "", prefix);
            multiFile.transferTo(file);
            analysisList = POIUtils.analysis(file, 1, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (CollectionUtils.isEmpty(analysisList)) {
            return Response.error("模板内容不能为空！");
        }
        DeviceTypeDto deviceTypeDto = deviceTypeService.selectCacheById(Long.valueOf(deviceTypeId.toString()));
        if (deviceTypeDto == null) {
            return Response.error("设备类型不存在！");
        }
        boolean isAnalysisOver = true;
        for (Map<Integer, String> excelDataMap : analysisList) {
            if (StringUtils.isBlank((String) excelDataMap.get(0)) ||
                    StringUtils.isBlank((String) excelDataMap.get(1)) ||
                    StringUtils.isBlank((String) excelDataMap.get(2)) ||
                    StringUtils.isBlank((String) excelDataMap.get(4)) ||
                    StringUtils.isBlank((String) excelDataMap.get(7))
            ) {
                return Response.error("模板内容有必填项未填！");
            }
            DeviceColumnDto deviceColumnDto = new DeviceColumnDto();
            DeviceColumnDto columnDto = deviceColumnService.queryByDeviceTypeIdAndName(Long.valueOf(deviceTypeId.toString()), (String) excelDataMap.get(0));
            if (columnDto != null) {
                responseDataList.add((String) excelDataMap.get(0));
                isAnalysisOver = false;
                continue;
            }
            //填充基础数据
            fillSaveCommonData(deviceColumnDto);
            deviceColumnDto.setDeviceTypeId(deviceTypeDto.getId());
            deviceColumnDto.setDeviceCategoryId(deviceTypeDto.getDeviceCategoryId());

            deviceColumnDto.setEntityName((String) excelDataMap.get(0));
            deviceColumnDto.setCnName((String) excelDataMap.get(1));
            deviceColumnDto.setDefaultValue((String) excelDataMap.get(2));
            deviceColumnDto.setColumnShow(Byte.valueOf((String) excelDataMap.get(3)));
            deviceColumnDto.setRemark((String) excelDataMap.get(4));
            deviceColumnDto.setUnit((String) excelDataMap.get(5));
            deviceColumnDto.setFieldType(Byte.valueOf((String) excelDataMap.get(6)));

            deviceColumnService.save(deviceColumnDto);
        }
        if (isAnalysisOver) {
            return Response.ok();
        } else {
            return Response.error("以下字段平台已经存在，上传失败字段如下：" + responseDataList.toString());
        }
    }

    /**
     * 导出字段
     *
     * @param params
     * @param httpServletResponse
     */
    @GetMapping("export")
    @Operation(summary = "导出字段")
    public void export(@RequestParam Map<String, Object> params, HttpServletResponse httpServletResponse) {

        //查询列表数据
        Request request = Request.configParams(params);

        /*super.fillAuthorityData(params);

        List<DeviceTypeDto> deviceTypeDtos = deviceTypeService.queryList(params);
        DeviceTypeDto deviceTypeDto=null;
        if(!CollectionUtils.isEmpty(deviceTypeDtos)){
            deviceTypeDto=deviceTypeDtos.get(0);
            params.put("deviceTypeId", deviceTypeDto.getId());
        }*/

        //查询列表数据 防止数据过大分页查询
        List<DeviceColumnDto> allList = new ArrayList<>();
        int pageNo = 0;
        while (true) {
            params.put("limit", 1000);
            params.put("offset", (++pageNo - 1) * 1000);
            List<DeviceColumnDto> list = deviceColumnService.queryList(params);
            if (list != null && list.size() <= 0) {
                break;
            }
            allList.addAll(list);

        }
        String[] headers = new String[]{"entityName", "cnName", "defaultValue", "columnShow", "remark", "unit", "fieldType"};

        List<String[]> dataList = new ArrayList<>();
        for (DeviceColumnDto deviceColumnDto : allList) {

            String[] item = new String[headers.length];
            item[0] = deviceColumnDto.getEntityName();
            item[1] = deviceColumnDto.getCnName();
            item[2] = deviceColumnDto.getDefaultValue();
            item[3] = deviceColumnDto.getColumnShow() + "";
            item[4] = deviceColumnDto.getRemark();
            item[5] = deviceColumnDto.getUnit();
            item[6] = deviceColumnDto.getFieldType() + "";
            dataList.add(item);
        }

        POIUtils.exportExcel(httpServletResponse, "Sheet1", headers, dataList, "deviceColumnsList.xls");
    }

    /**
     * 列表
     */
    @GetMapping("queryColumnByDeviceType")
    @Operation(summary = "根据条件查询列表")
    public Response<List<DeviceColumnDto>> queryColumnByDeviceType(@RequestParam Long deviceTypeId) {
        //查询列表数据
        //Request request = Request.configParams(new HashMap<>());
        Map<String, Object> request = new HashMap<>();
        request.put("deviceTypeId", deviceTypeId);
        request.put("columnShow", "1");

        List<DeviceColumnDto> list = deviceColumnService.queryList(request);

        return Response.<List<DeviceColumnDto>>ok().wrap(list);
    }

    /**
     * 列表
     */
    @GetMapping("list")
    @RequirePermissions(values = "deviceColumn:list")
    @Operation(summary = "设备物模型的查询分页列表")
    public Response<Page<DeviceColumnDto>> list(@RequestParam Map<String, Object> params) {
        //查询列表数据
        Request request = Request.configParams(params).like("name");

        List<DeviceColumnDto> list = deviceColumnService.queryList(params);
        int total = deviceColumnService.queryTotal(params);

        Page<DeviceColumnDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<DeviceColumnDto>>ok().wrap(page);
    }


    /**
     * 信息
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "deviceColumn:info")
    @Operation(summary = "查询单条设备物模型信息")
    public Response<DeviceColumnDto> info(@PathVariable("id") Long id) {

        DeviceColumnDto deviceColumnDto = deviceColumnService.selectById(id);

        return Response.<DeviceColumnDto>ok().wrap(deviceColumnDto);
    }

    /**
     * 保存
     */
    @PostMapping("save")
    @RequirePermissions(values = "deviceColumn:edit")
    @RequireTenants(values = SysConstants.SYS_TOP_TENANT_CODE)
    @Operation(summary = "保存单条设备物模型信息")
    public Response<Object> save(@RequestBody @Validated DeviceColumnDto deviceColumnDto) {

        //填充基础数据
        fillSaveCommonData(deviceColumnDto);

        deviceColumnService.save(deviceColumnDto);

        return Response.ok();
    }

    @PostMapping("columnInfoSave")
    @RequirePermissions(values = "deviceColumn:edit")
    @RequireTenants(values = SysConstants.SYS_TOP_TENANT_CODE)
    @Operation(summary = "设备物模型保存")
    @Log(express = "设备物模型保存")
    public Response<Object> columnInfosave(@RequestBody @Validated Map<String, Object> params) {
        Long deviceTypeId = Long.valueOf(params.get("deviceTypeId") + "");
        List<DeviceColumnDto> deviceColumnDtos = JacksonUtils.parseArray(JacksonUtils.toJsonString(params.get("deviceColumnDtos")), DeviceColumnDto.class);

        DeviceTypeDto deviceTypeDto = deviceTypeService.selectById(deviceTypeId);
        if (deviceTypeDto == null) {
            return Response.error("未找到类型");
        }
        deviceColumnService.deleteByDeviceTypeId(deviceTypeId);
        for (DeviceColumnDto deviceColumnDto : deviceColumnDtos) {
            deviceColumnDto.setDeviceTypeId(deviceTypeId);
            deviceColumnDto.setDeviceTypeName(deviceTypeDto.getName());
            deviceColumnDto.setDeviceCategoryId(deviceTypeDto.getDeviceCategoryId());
            deviceColumnDto.setDeviceCategoryName(deviceTypeDto.getDeviceCategoryName());
            deviceColumnService.save(deviceColumnDto);
        }
        return Response.ok();
    }

    /**
     * 修改
     */
    @PostMapping("update")
    @RequirePermissions(values = "deviceColumn:edit")
    @RequireTenants(values = SysConstants.SYS_TOP_TENANT_CODE)
    @Operation(summary = "修改单条设备物模型记录")
    public Response<Object> update(@RequestBody @Validated DeviceColumnDto deviceColumnDto) {

        //填充基础数据
        fillEditCommonData(deviceColumnDto);

        deviceColumnService.updateById(deviceColumnDto);

        return Response.ok();
    }

    /**
     * 删除
     */
    @PostMapping("delete")
    @RequirePermissions(values = "deviceColumn:delete")
    @RequireTenants(values = SysConstants.SYS_TOP_TENANT_CODE)
    @Operation(summary = "批量删除存在设备物模型记录")
    public Response<Object> delete(@RequestBody Long[] ids) {

        deviceColumnService.deleteBatch(ids);

        return Response.ok();
    }

    @GetMapping("queryAllColumnList")
    @Operation(summary = "根据条件查询设备物模型记录")
    public Response<List<DeviceColumnDto>> queryAllColumnList(@RequestParam Map<String, Object> params) {
        //查询列表数据
        Request request = Request.configParams(params).like("name");
        /*//查询列表数据
        Request request = Request.configParams(new HashMap<>());
        request.put("deviceTypeId", deviceTypeId);
        request.put("columnShow", "1");*/

        List<DeviceColumnDto> list = deviceColumnService.queryAllColumnList(request.getParams());

        return Response.<List<DeviceColumnDto>>ok().wrap(list);
    }
}
